package us.norepeter.processing.textmatcher;

import processing.core.PApplet;

public abstract class RegexScorer 
	extends TextProcessingChainLink implements Scorer {

	String matcher;
	String property;
	String compareToProperty;
	int index;
	int trueScore;
	int falseScore;

	RegexScorer(String propertyName, String regexString) {
		this(propertyName, propertyName, regexString);
	}

	RegexScorer( String propertyName,
			String compareToPropertyName, String regexString) {
		this(propertyName, compareToPropertyName, regexString, 1, 0, 0);
	}

	RegexScorer( String propertyName,
			String compareToPropertyName, String regexString, int index,
			int trueScore, int falseScore) {
		matcher = regexString;
		property = propertyName;
		compareToProperty = compareToPropertyName;
		this.index = index;
		this.trueScore = trueScore;
		this.falseScore = falseScore;
	}

	@Override
	public int getScore(Entity e1, Entity e2) {
		String prop1 = e1.getProperty(property);
		String prop2 = e2.getProperty(compareToProperty);
		if (index < 0) {
			return getScore(prop1, getMatch(prop1), prop2, getMatch(prop2));
		}
		return getScore(getIndexMatch(prop1), getIndexMatch(prop2));
	}

	String[] getMatch(String propname, String regex) {
		String[] m1 = PApplet.match(propname, regex);
		return (m1 == null) ? new String[0] : m1;
	}

	String getMatch( String propname, String regex, int index ) {
	    String[] m1 = PApplet.match( propname, regex );
	    String ret = "";
	    index = PApplet.constrain( index, 0, m1.length-1 );
	    if ( m1 != null && index >= 0 && index < m1.length ) {
	      return m1[index];
	    }
	    return ret;
	  }

	String[] getMatch(String propname) {
		return getMatch(propname, matcher);
	}

	String getIndexMatch(String propname) {
		return getMatch(propname, matcher, index);
	}

	/**
	 * override me
	 **/
	int getScore(String s1, String[] comp1, String s2, String[] comp2) {
		return 0;
	}

	/**
	 * override me
	 **/
	int getScore(String s1, String s2) {
		return (s1.equals(s2)) ? trueScore : falseScore;
	}
}
